#set( $symbol_pound = '#' )
#set( $symbol_dollar = '$' )
#set( $symbol_escape = '\' )
/*
 * Copyright © 2014, Finium Sdn Bhd, All Rights Reserved
 * 
 * EnumUserType.java
 * Modification History
 * *************************************************************
 * Date				Author						Comment
 * Feb 09, 2012		Venkaiah Chowdary Koneru	Created
 * *************************************************************
 */
package ${package}.support;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Properties;

import ${package}.AppConstants;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.EnhancedUserType;
import org.hibernate.usertype.ParameterizedType;

/**
 * Support for mapping Java enumerated types through Hibernate. See
 * http://www.hibernate.org/272.html for more information and discussion.
 * 
 * @author Gavin King
 * 
 *         and Modified By Venkaiah Chowdary Koneru to support hibernate 4.
 */
@SuppressWarnings("unchecked")
public class EnumUserType implements EnhancedUserType, ParameterizedType
{

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    private Class<Enum> enumClass;

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public void setParameterValues(Properties parameters)
    {
        String enumClassName = parameters.getProperty("enumClassName");
        try
        {
            enumClass = (Class<Enum>) Class.forName(enumClassName);
        }
        catch (ClassNotFoundException cnfe)
        {
            throw new HibernateException("Enum class not found", cnfe);
        }
    }

    @Override
    public Object assemble(Serializable cached, Object owner)
    {
        return cached;
    }

    @Override
    public Object deepCopy(Object value)
    {
        return value;
    }

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public Serializable disassemble(Object value)
    {
        return (Enum) value;
    }

    @Override
    public boolean equals(Object x, Object y)
    {
        if (x == null || y == null)
        {
            return false;
        }

        return x.equals(y);
    }

    @Override
    public int hashCode(Object x)
    {
        return x.hashCode();
    }

    @Override
    public boolean isMutable()
    {
        return false;
    }

    @Override
    public Object nullSafeGet(ResultSet rs, String[] names,
            SessionImplementor implementor, Object owner) throws SQLException
    {
        String name = rs.getString(names[0]);
        return rs.wasNull() ? null : Enum.valueOf(enumClass, name);
    }

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public void nullSafeSet(PreparedStatement st, Object value, int index,
            SessionImplementor implementor) throws SQLException
    {
        if (value == null)
        {
            st.setNull(index, Types.VARCHAR);
        }
        else
        {
            st.setString(index, ((Enum) value).name());
        }
    }

    @Override
    public Object replace(Object original, Object target, Object owner)
    {
        return original;
    }

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public Class returnedClass()
    {
        return enumClass;
    }

    @Override
    public int[] sqlTypes()
    {
        return new int[] { Types.VARCHAR };
    }

    @Override
    public Object fromXMLString(String xmlValue)
    {
        return Enum.valueOf(enumClass, xmlValue);
    }

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public String objectToSQLString(Object value)
    {
        return '${symbol_escape}'' + ((Enum) value).name() + '${symbol_escape}'';
    }

    @SuppressWarnings(AppConstants.SUPPRESS_WARNINGS_RAWTYPES)
    @Override
    public String toXMLString(Object value)
    {
        return ((Enum) value).name();
    }
}
